﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AutoMapper;
using danreng.Domain;
using danreng.Enum;
using sharp_net;
using sharp_net.Repositories;
using sharp_net.Specifications;

namespace danreng.Application {
    public interface IUserService {
        UserData Get(int ID);
        IEnumerable<UserData> GetListPager(ref int count, int pageSize = 10, int pageIndex = 1);
        UserData Creat(UserData dataObject);
        void Update(UserData dataObject);

        UserData GetByLogin(string email, string password);
        bool CheckUserExist(UserData data, ref string existFields);
    }

    public class UserApplication : BaseApplication, IUserService {
        private IRepositoryContext Context {
            get { return IocLocator.Instance.GetImple<IRepositoryContext>(eDbType.Mongo.ToString(), new { settingkey = eDbHost.Mongo_Main.ToString() }); }
        }

        public UserData Get(int ID) {
            using (var context = Context) {
                var repo = context.GetRepository<User>();
                var item = repo.GetById(ID);
                if (item == null)
                    return null;
                var itemData = Mapper.Map<User, UserData>(item);
                return itemData;
            }
        }

        public UserData GetByLogin(string email, string password) {
            using (var context = Context) {
                var repo = context.GetRepository<User>();
                User user = repo.Find(Specification<User>.Eval(c => c.Email == email && c.Equals(password)));
                if (user == null)
                    return null;
                UserData userData = Mapper.Map<User, UserData>(user);
                return userData;
            }
        }

        public bool CheckUserExist(UserData data, ref string existFields) {
            using (var context = Context) {
                var repo = context.GetRepository<User>();
                if (!string.IsNullOrEmpty(data.Email) && repo.Exists(Specification<User>.Eval(c => c.Email == data.Email))) {
                    existFields = String.Format("Email '{0}' 已存在.", data.Email);
                    return false;
                }
                if (!string.IsNullOrEmpty(data.DisplayName) && repo.Exists(Specification<User>.Eval(c => c.DisplayName == data.DisplayName))) {
                    existFields = String.Format("用户名 '{0}' 已存在.", data.DisplayName);
                    return false;
                }
                return true;
            }
        }

        public IEnumerable<UserData> GetListPager(ref int count, int pageSize = 10, int pageIndex = 1) {
            using (var context = Context) {
                var repo = context.GetRepository<User>();
                var items = repo.FindAll(pageIndex, pageSize);
                if (items == null || items.Count() == 0)
                    return null;
                count = repo.FindAll().Count();
                var itemDatas = new List<UserData>();
                foreach (var item in items) {
                    itemDatas.Add(Mapper.Map<User, UserData>(item));
                }
                return itemDatas;
            }
        }

        public UserData Creat(UserData dataObject) {
            if (dataObject == null)
                throw new ArgumentNullException("itemDataObject");
            using (var context = Context) {
                var repo = context.GetRepository<User>();
                User item = Mapper.Map<UserData, User>(dataObject);
                item.Creat();
                repo.Add(item);
                context.Commit();
                return Mapper.Map<User, UserData>(item);
            }
        }

        public void Update(UserData data) {
            if (string.IsNullOrEmpty(data.Id))
                throw new ArgumentNullException("ID");
            using (var context = Context) {
                var repo = context.GetRepository<User>();
                var item = repo.GetById(data.Id);
                if (data.ActEnum == (int)eAct.Delete) {
                    repo.Remove(item);
                    return;
                }
                item.Update(data);
                repo.Update(item);
            }
        }
    }
}
